//
//  "$Id: VideoDetect.h 91860 2012-12-08 09:18:30Z li_weijun $"
//
//  Copyright (c)1992-2007, ZheJiang Dahua Technology Stock CO.LTD.
//  All Rights Reserved.
//
//	Description:	
//	Revisions:		Year-Month-Day  SVN-Author  Modification
//

#ifndef __VIDEO_DETECT_API_H__
#define __VIDEO_DETECT_API_H__

#include "Types.h"
#include "Defs.h"

#ifdef __cplusplus
extern "C" {
#endif

/// \defgroup VideoDetectAPI API Video Detector
/// 视频检测接口
///	\n 调用流程图:
/// \code
///    ===========================
///                |
///        *createVideoDetector
///                |
///             addRef
///                |
///             getCaps
///                |---------------+
///          detectBlind  setBlindParameter
///           delteLoss            |
///         detectMotion  setMotionParameter
///                |---------------|
///             release
///                |
///    ===========================
/// \endcode
/// @{

/* 运动检测类型 */
typedef enum
{
    DETECT_VIDEO_MD  = 0,   /* 普通类型MD模块，SAD值算法 */
    DETECT_VIDEO_SMD = 1,   /* Smart Motion Detection有人告警 */
    DETECT_VIDEO_MAX        /* 无效值 */
} VideoDetectType;

/// 视频检测设备特性结构，128字节
typedef struct VideoDetectCaps
{
	char blind;                ///< 是否支持遮挡检测
	char loss;			       ///< 是否支持丢失检测
	char motion;	           ///< 是否支持动态检测
	char motionResult;	       ///< 是否能得到每块区域的检测结果。
	int motionColumns;	       ///< 动态检测的区域需要划分成的列数。
	int motionRows;		       ///< 动态检测的区域需要划分成的行数。
	char bodyMotion:1;        ///< 是否支持人形报警,非运动也会报警
	char bodyMotionResult:1;  ///< 人形报警是否能得到每块区域的检测结果。
    char reservedBit:6;        ///< 保留bit
    char bodyMotionColumns;   ///< 人形报警检测的区域需要划分成的列数
    char bodyMotionRows;      ///< 人形报警检测的区域需要划分成的行数
    char motionSupportMask;    ///< motion可同时运行多类型掩码，VideoDetectType左移
	int reserved[28];	///< 保留
} VideoDetectCaps;


/// 视频丢失检测参数，32位系统下128字节
typedef struct VideoDetectLossParam
{
	char	enable;			///< 为1表示使能，为0时表示禁用
	int reserved[31];		///< 保留
} VideoDetectLossParam;


/// 黑屏检测参数，32位系统下128字节
typedef struct VideoDetectBlindParam
{
	char	enable;			///< 为1表示使能，为0时表示禁用
	char	level;         ///< 灵敏度，等级1-6
	int reserved[31];		///< 保留
} VideoDetectBlindParam;

#define MD_REGION_ROW 18

/// 动态检窗口区域设置,128字节
typedef struct VideoDetectWindow
{
	/// 动检窗口区域
	ulong	win[MD_REGION_ROW];

	/// 灵敏度，取值[0, 100]
	uchar sensitive;
	
	/// 面积阀值，取值[0, 100]
	uchar threshold;
	
	/// 窗口id，用于标示窗口号
	ushort id;	
	
	int reserved[13];
} VideoDetectWindow;


/// 动态检测参数，128字节
typedef struct VideoDetectMotionParam
{
	/// 使能开关，是否使能，为1表示使能，为0时表示禁用，其他参数被忽略。
	char	enable;

	/// 动态检测的敏感度档次，等级1-6
	char	level;

	/// 灵敏度的具体值，暂不使用
	char	sensitiveness;

	/// 帧间隔，暂不使用
	char	fieldinterval;

	/// 动态检测的区域，数据的每一位对应一个矩形区域块，置1表示需要在该区域块动
	/// 态检测，置0表示不需要在该区域块动态检测。每一行用一个ulong表示，最左边的
	/// 块对应最低位，从上到下的行对应的下标从0到17。支持的行列数之外对应的数据
	/// 位无效。
	ulong	win[MD_REGION_ROW];

	///< 面积占用比, 1-100，0 表示此配置无效
	uchar volumeRatio;

	///< 动检的残差阈值, 1-100，0 表示此配置无效
	uchar subRatio;
	
	/// 使用新的动检模式[0, 表示使用老的模式, 1表示使用新的模式]
	uchar newMode;	
	
	/// 动检窗口数
	uchar windowNum;
	
	/// 动检窗口数组
	VideoDetectWindow *detectWindows;

	///< 保留
	int reserved[11];
}VideoDetectMotionParam;

/// 动态检测结果，128字节
typedef struct VideoDetectWindowResult
{
	/// 窗口id，用于标示窗口号
	ushort id;	
	
	/// 区域的移动侦测的状态, 0表示无动检，1表示有动检。
	uchar state;
	
	/// 移动侦测的状态值（动检移动百分比[0, 100]）
	uchar status;
	
	/// 有动态检测发生的区域，数据的每一位对应一个矩形区域块，置1表示在该区域块
	/// 动态检测成功，置0表示该区域块动态检测失败。每一行用一个ulong表示，最左边
	/// 的块在最高位，从上到下的行对应的下标从0到17。支持的行列数之外对应的数据
	/// 位无效。
	ulong	win[18];
	
	int reserved[13];
} VideoDetectWindowResult;

/// 动态检测结果，128字节
typedef struct VideoDetectMotionResult
{
	/// 有动态检测发生的区域，数据的每一位对应一个矩形区域块，置1表示在该区域块
	/// 动态检测成功，置0表示该区域块动态检测失败。每一行用一个ulong表示，最左边
	/// 的块在最高位，从上到下的行对应的下标从0到17。支持的行列数之外对应的数据
	/// 位无效。
	ulong	win[18];
	
	/// 最大的窗口数，上层传NULL表示之前老的方式获取动检状态
	ulong *maxWindow;
	
	/// 动检窗口
	VideoDetectWindowResult *windowResult;
	
	///< 保留
	int reserved[12];
}VideoDetectMotionResult;


/// 人形检测结果，128字节
typedef struct VideoBodyMotionResult
{
	/// 是否存在人形，0不存在，1存在
	uchar isBody;
	
	///< 保留
	uchar reservedByte[3];
	int reserved[31];
}VideoBodyMotionResult;


/// 视频检测接口，512字节
typedef struct VideoDetector
{
	/// 底层私有数据
	void *priv;


	/// 增加接口引用
	int (*addRef)(struct VideoDetector *thiz);


	/// 释放接口
	int (*release)(struct VideoDetector *thiz);


	/// 得到黑屏支持的特性。
	/// 
	/// \param [in] thiz 视频检测接口指针
	/// \param [out] caps 指向黑屏特性结构VideoDetectCaps的指针。
	/// \retval 0  获取成功。
	/// \retval <0  获取失败。
	int (*getCaps)(struct VideoDetector *thiz, VideoDetectCaps * caps);


	/// 执行遮挡检测，返回自上次检测到这次检测之间是否有遮挡事件。
	/// 
	/// \param [in] thiz 视频检测接口指针
	/// \retval 0  未被遮挡
	/// \retval 1  已被遮挡
	/// \retval <0  检测失败。
	int (*detectBlind)(struct VideoDetector *thiz);


	/// 执行丢失检测，返回自上次检测到这次检测之间是否有丢失事件。
	/// 
	/// \param [in] thiz 视频检测接口指针
	/// \retval 0  未丢失
	/// \retval 1  已丢失
	/// \retval <0  检测失败。
	int (*detectLoss)(struct VideoDetector *thiz);


	/// 执行视频丢失检测。立即返回。
	/// 
	/// \param [in] thiz 视频检测接口指针
	/// \param [in] result 指向黑屏检测参数结构VideoDetectParam的指针。
	/// \retval 0  无动检
	/// \retval 1  有动检
	/// \retval <0  检测失败。
	int (*detectMotion)(struct VideoDetector *thiz, VideoDetectMotionResult* result);


	/// 设置黑屏检测的参数。
	/// 
	/// \param [in] thiz 视频检测接口指针
	/// \param [in] param 指向黑屏检测参数结构VideoDetectParam的指针。
	/// \retval 0  设置成功
	/// \retval <0  设置失败
	int (*setBlindParameter)(struct VideoDetector *thiz, VideoDetectBlindParam *param);


	/// 设置动态检测的参数。
	/// 
	/// \param [in] thiz 视频检测接口指针
	/// \param [in] param 指向动态检测参数结构MotionDetectParam的指针。
	/// \retval 0  设置成功
	/// \retval <0  设置失败
	int (*setMotionParameter)(struct VideoDetector *thiz, VideoDetectMotionParam *param);


	/// 设置视频丢失检测的参数。
	/// 
	/// \param [in] thiz 视频检测接口指针
	/// \param [in] param 指向视频丢失参数结构 VideoDetectLossParam 的指针。
	/// \retval 0  设置成功
	/// \retval <0  设置失败
	int (*setLossParameter)(struct VideoDetector *thiz, VideoDetectLossParam *param);


    /// 设置人形报警的参数。
	/// 
	/// \param [in] thiz 视频检测接口指针
	/// \param [in] param 指向动态检测参数结构MotionDetectParam的指针。
	/// \retval 0  设置成功
	/// \retval <0  设置失败
	int (*setbodyParameter)(struct VideoDetector *thiz, VideoDetectMotionParam *param);


    /// 人形报警
	/// \param [in] thiz 视频检测接口指针
	/// \param [in] result 指向动检结果结构VideoBodyMotionResult的指针。
	/// \retval 0  无动检
	/// \retval 1  有动检
	/// \retval <0  检测失败。
	int (*bodyMotion)(struct VideoDetector *thiz, VideoBodyMotionResult* result);


	///< 保留
	void* reserved[116];

} VideoDetector;


/// 视频检测接口描述，128字节
typedef struct VideoDetectDesc
{
	int	channel;		///< 检测的视频输入物理通道号
	int card;			///< 子卡槽位号，0表示主板，>0表示子卡
	int reserved[30];	///< 保留
} VideoDetectDesc;


/// 创建视频检测接口
///
/// \param [in] dest 视频检测接口描述结构VideoDetectDesc指针
/// \param [out] videoDetector 视频检测指针的指针
/// \retval <0 创建失败
/// \retval 0 创建成功
int PAL_API createVideoDetector(VideoDetectDesc *desc, VideoDetector **videoDetector);


/// @} end of group

#ifdef __cplusplus
}
#endif

#endif //__VIDEO_DETECT_API_H__

